package no.ntnu.fp.gui.dialog;

import java.awt.CardLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

import no.ntnu.fp.gui.EventDispatcher;
import no.ntnu.fp.gui.events.EmployeesRequestedEvent;
import no.ntnu.fp.model.Employee;
import no.ntnu.fp.model.events.DialogEmployeesChangeEvent;
import no.ntnu.fp.model.listeners.ModelListener;
import no.ntnu.fp.utils.Participant;
/**
 * This class is meant to be the the dialog where you can get the all the employees
 * and select participants to use later
 * @author nordmoen
 *
 */
@SuppressWarnings("serial")
public class ParticipantDialog extends JDialog implements 
ModelListener<DialogEmployeesChangeEvent>{
	private AllEmployeeTableModel model;
	private JProgressBar progress;
	private JPanel cards;
	private JScrollPane scroll;
	private boolean canceled;
	final static String CONTENT = "content of dialog";
	final static String LOAD = "progressbar of dialog";

	private static ParticipantDialog instance;

	public static void createInstance() {
		if (instance == null) {
			instance = new ParticipantDialog();
		}else{
			throw new IllegalStateException("ParticipantDialog instance exists!");
		}
	}

	public static ParticipantDialog getInstance() {
		if(instance == null){
			throw new IllegalStateException("ParticipantDialog instance does not exist!");
		}else{
			return instance;
		}
	}
	//This needs a parent so we it becomes modal!
	private ParticipantDialog(){
		this.setModalityType(ModalityType.APPLICATION_MODAL);
		this.setTitle("Velg kalendere");
		this.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
		this.canceled = true;

		JPanel content = new JPanel();
		JPanel loadBarPanel = new JPanel();
		cards = new JPanel(new CardLayout());

		content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
		model = new AllEmployeeTableModel();
		JTable table = new JTable(model);
		table.getTableHeader().setReorderingAllowed(false);
		scroll = new JScrollPane(table);
		JPanel buttonPanel = new JPanel();
		JButton ok = new JButton("Bruk utvalg");
		ok.setAlignmentX(Component.RIGHT_ALIGNMENT);
		ok.addActionListener(new OkButtonAction());
		JButton cancel = new JButton("Avbryt");
		cancel.setAlignmentX(Component.RIGHT_ALIGNMENT);
		cancel.addActionListener(new CancelButtonAction());

		progress = new JProgressBar(JProgressBar.HORIZONTAL);
		progress.setString("Henter alle ansatte");
		progress.setStringPainted(true);

		loadBarPanel.add(progress);

		buttonPanel.add(ok);
		buttonPanel.add(cancel);
		content.add(scroll);
		content.add(buttonPanel);

		cards.add(content, CONTENT);
		cards.add(loadBarPanel, LOAD);
		this.add(cards);
		this.pack();
	}
	
	public boolean isCanceled(){
		return canceled;
	}

	@Override
	public void handleEvent(DialogEmployeesChangeEvent event) {
		model.clear();
		model.putAll(event.getParticipants());
		this.progress.setIndeterminate(false);
		((CardLayout)cards.getLayout()).show(cards, CONTENT);
	}

	public void show(Component parent){
		EventDispatcher.dispatchEvent(new EmployeesRequestedEvent(this));
		((CardLayout)cards.getLayout()).show(cards, LOAD);
		this.progress.setIndeterminate(true);
		this.canceled = true;
		this.setLocationRelativeTo(parent);
		this.setVisible(true);
	}

	public List<Employee> getAllSelectedParticipants(){
		List<Employee> selected = new ArrayList<Employee>();
		for(Participant p : model.getParticipantsList()){
			if(p.isAttending()){
				selected.add(p.getEmployee());
			}
		}
		return selected;
	}

	private final class AllEmployeeTableModel extends AbstractTableModel{
		private ArrayList<Participant> participants = new ArrayList<Participant>();
		private String[] header = {"Navn", "Valgt"};

		@Override
		public int getColumnCount() {
			return 2;
		}
		@Override
		public int getRowCount() {
			return participants.size();
		}
		@SuppressWarnings({ "unchecked"})
		@Override
		public Class getColumnClass(int c) {
			return getValueAt(0, c).getClass();
		}
		@Override
		public Object getValueAt(int arg0, int arg1) {
			if(arg1 == 1){
				return participants.get(arg0).isAttending();
			}else{
				return participants.get(arg0).getEmployee().getName();
			}
		}
		@Override
		public String getColumnName(int col){
			return header[col];
		}
		@Override
		public boolean isCellEditable(int row, int col){
			if(col == 1){
				return true;
			}else{
				return false;
			}
		}
		@Override
		public void setValueAt(Object value, int row, int col){
			if(col == 1){
				Employee e = participants.get(row).getEmployee();
				participants.remove(row);
				participants.add(row, new Participant(e, (Boolean) value));
			}
		}
		public void putAll(List<Employee> employees){
			for(Employee e : employees){
				this.participants.add(new Participant(e, false));
			}
			this.fireTableRowsInserted(0, this.participants.size());
		}
		public void clear(){
			this.participants.clear();
		}
		public ArrayList<Participant> getParticipantsList(){
			return this.participants;
		}

	}
	public final class OkButtonAction implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent arg0) {
			ParticipantDialog.this.setVisible(false);
			ParticipantDialog.this.canceled = false;
		}
	}
	public final class CancelButtonAction implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e) {
			ParticipantDialog.this.setVisible(false);
			ParticipantDialog.this.canceled = true;
		}
	}

}
